﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NBlock.Core.ORM;
using Cost.Models;

namespace Cost.Services
{
    /// <summary>
    /// 菜肴的服务类
    /// </summary>
    public class DishService
    {
        #region 构造函数
        private readonly ICostRepository<Dish> dishRepository;
        private readonly ICostRepository<Material> materialRepository;
        private readonly ICostRepository<DishMaterial> dishMaterialRepository;
        private readonly MaterialService materialService;

        public DishService(ICostRepository<Dish> dishRepository,
            ICostRepository<Material> materialRepository,
            ICostRepository<DishMaterial> dishMaterialRepository,
            MaterialService materialService)
        {
            this.dishRepository = dishRepository;
            this.materialRepository = materialRepository;
            this.dishMaterialRepository = dishMaterialRepository;
            this.materialService = materialService;
        }
        #endregion

        public IList<DishMaterial> GetDishMaterials(string dishId)
        {
            var details = dishMaterialRepository.FindAll(d => d.DishId == dishId).ToList();
            details.ForEach(d =>
            {
                d.CurrentPrice = materialService.GetMaterialPrice(d.MaterialId, d.NeedProcess);
                d.Cost = CalcSingleCost(d.MaterialId, d.Weight, d.Unit, d.NeedProcess);
            });
            return details;
        }

        public Dish GetDish(string dishId)
        {
            var data = dishRepository.Find(dishId);
            if (data == null)
            {
                data = new Dish();
                data.Cost = GetDishCost(dishId);
            }

            return data;
        }

        /// <summary>
        /// 获取指定菜肴的成本
        /// </summary>
        /// <returns></returns>
        public decimal GetDishCost(string dishId, List<DishMaterial> details = null)
        {
            decimal dishCost = 0;
            if (details != null)
            {
                foreach (var detail in details)
                {
                    dishCost += CalcSingleCost(detail.MaterialId, detail.Weight, detail.Unit, detail.NeedProcess);
                }

                return dishCost;
            }
            else
            {
                var detailsInDB = dishMaterialRepository.FindAll(d => d.DishId == dishId)
                            .Select(d => new
                            {
                                d.MaterialId,
                                d.Unit,
                                d.Weight,
                                d.NeedProcess
                            }).ToList();

                foreach (var detail in detailsInDB)
                {
                    dishCost += CalcSingleCost(detail.MaterialId, detail.Weight, detail.Unit, detail.NeedProcess);
                }

                return dishCost;
            }
        }

        /// <summary>
        /// 计算单个品名的成本
        /// </summary>
        /// <returns></returns>
        private decimal CalcSingleCost(string materialId, decimal weight, string unit, bool needProcess)
        {
            // 获取品名的当前单价
            var price = materialService.GetMaterialPrice(materialId, needProcess);

            return Math.Ceiling(price * (weight / Decimal.Parse(unit)) * 100) / 100; 
        }
    }
}
